package model

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"

	"gitee.com/dhcy/tencent_ddns/xlog"

	"gitee.com/dhcy/tencent_ddns/conf"
	"gitee.com/dhcy/tencent_ddns/tostring"
)

// HostDomain 域名结构
type HostDomain struct {
	Token     string
	Domain    string
	SubDomain string
}

//Records 域名参数
type Records struct {
	Id     string
	Ip     string
	typ    string
	lineId string
}

// NewRecords 创建域名参数
func NewRecords(id, ip, typ, lineId string) *Records {
	return &Records{
		Id:     id,
		Ip:     ip,
		typ:    typ,
		lineId: lineId,
	}
}

// NewDomain 创建域名结构
func NewDomain(token, domain, subDomain string) *HostDomain {
	return &HostDomain{
		Token:     token,
		Domain:    domain,
		SubDomain: subDomain,
	}
}

// UpdateDomainIp 更新域名IP
func (h *HostDomain) UpdateDomainIp(publicIp string) error {
	// 获取当前域名IP信息
	records, err := h.getDomainIp()
	if err != nil {
		return err
	}
	// 当前IP不匹配就修改成传入IP
	if records.Ip != publicIp {
		err = h.setDomainIp(records, publicIp)
		if err != nil {
			return err
		}
		xlog.Info(fmt.Sprintf("set ip ok %s.%s ip:%s==>%s", h.SubDomain, h.Domain, records.Ip, publicIp))
	}
	return nil
}

// getDomainIp 获取域名IP
func (h *HostDomain) getDomainIp() (*Records, error) {
	// 组装表单数据
	urlValue := url.Values{}
	urlValue.Add("login_token", h.Token)
	urlValue.Add("format", "json")
	urlValue.Add("domain", h.Domain)
	urlValue.Add("sub_domain", h.SubDomain)
	urlValue.Add("record_type", "A")
	urlValue.Add("offset", "0")
	urlValue.Add("lenght", "3")
	// 访问腾讯云API
	resp, err := http.PostForm(conf.GetDomainIpApi, urlValue)
	if err != nil {
		return nil, fmt.Errorf("get tencent ip err:%v", err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("read get tencent ip body err:%v", err)
	}
	id, ip, typ, lineId, err := tostring.GetDomainIp(body)
	if err != nil {
		return nil, err
	}
	return NewRecords(id, ip, typ, lineId), nil
}

// setDomainIp 设置域名IP
func (h *HostDomain) setDomainIp(records *Records, publicIp string) error {
	// 组装表单数据
	urlValue := url.Values{}
	urlValue.Add("login_token", h.Token)
	urlValue.Add("format", "json")
	urlValue.Add("domain", h.Domain)
	urlValue.Add("sub_domain", h.SubDomain)
	urlValue.Add("record_id", records.Id)
	urlValue.Add("value", publicIp)
	urlValue.Add("record_type", records.typ)
	urlValue.Add("record_line_id", records.lineId)
	// 访问腾讯云API
	resp, err := http.PostForm(conf.SetDomainIpApi, urlValue)
	if err != nil {
		return fmt.Errorf("set tencent ip err:%v", err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return fmt.Errorf("read set tencent ip body err:%v", err)
	}
	return tostring.SetDomainIp(body)
}

// GetPublicIp 获取公网IP
func GetPublicIp() (string, error) {
	resp, err := http.Get(conf.GetPublicIpApi)
	if err != nil {
		return "", fmt.Errorf("get public ip server err:%v", err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("read get public ip body err:%v", err)
	}
	return tostring.GetPublicIp(body)
}
